package com.jsrana.idea.plugin.ideaweather.worker;

import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.openapi.wm.StatusBar;
import com.intellij.openapi.wm.WindowManager;
import com.jsrana.idea.plugin.ideaweather.IdeaWeatherPlugin;
import com.jsrana.idea.plugin.ideaweather.util.HttpUtil;
import com.jsrana.idea.plugin.ideaweather.widget.WeatherStatusBarWidget;

import javax.swing.*;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by jrana on 7/29/14.
 */
public class WeatherWorker
        extends SwingWorker {
    String response = "";

    @Override protected Object doInBackground()
            throws Exception {
        try {
            String woeid = PropertiesComponent.getInstance().getValue( IdeaWeatherPlugin.PROPERTY_WOEID );
            if ( woeid == null ) {
                woeid = IdeaWeatherPlugin.DEFAULT_WOEID;
            }
            String unit = PropertiesComponent.getInstance().getValue( IdeaWeatherPlugin.PROPERTY_UNIT );
            if ( unit == null ) {
                unit = IdeaWeatherPlugin.DEFAULT_UNIT;
            }
            response = HttpUtil.getText( "http://weather.yahooapis.com/forecastrss?w=" + woeid + "&u=" + unit );
        }
        catch ( Exception e ) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void done() {
        String message = "Weather data not available";
        String code = "30";
        if ( response != null && response.length() > 10 ) {
            // parse location
            String location = parseTag( response, "location" );
            IdeaWeatherPlugin.weather.put( "location_city", parseToken( location, "city" ) );
            IdeaWeatherPlugin.weather.put( "location_region", parseToken( location, "region" ) );
            IdeaWeatherPlugin.weather.put( "location_country", parseToken( location, "country" ) );

            // parse units
            String units = parseTag( response, "units" );
            IdeaWeatherPlugin.weather.put( "units_temperature", parseToken( units, "temperature" ) );
            IdeaWeatherPlugin.weather.put( "units_distance", parseToken( units, "distance" ) );
            IdeaWeatherPlugin.weather.put( "units_pressure", parseToken( units, "pressure" ) );
            IdeaWeatherPlugin.weather.put( "units_speed", parseToken( units, "speed" ) );

            // parse wind condition
            String wind = parseTag( response, "wind" );
            IdeaWeatherPlugin.weather.put( "wind_chill", parseToken( wind, "chill" ) );
            IdeaWeatherPlugin.weather.put( "wind_direction", parseToken( wind, "direction" ) );
            IdeaWeatherPlugin.weather.put( "wind_speed", parseToken( wind, "speed" ) );

            // parse atmosphere
            String atmosphere = parseTag( response, "atmosphere" );
            IdeaWeatherPlugin.weather.put( "atmosphere_humidity", parseToken( atmosphere, "humidity" ) );
            IdeaWeatherPlugin.weather.put( "atmosphere_visibility", parseToken( atmosphere, "visibility" ) );
            IdeaWeatherPlugin.weather.put( "atmosphere_pressure", parseToken( atmosphere, "pressure" ) );
            IdeaWeatherPlugin.weather.put( "atmosphere_rising", parseToken( atmosphere, "rising" ) );

            // parse astronomy
            String astronomy = parseTag( response, "astronomy" );
            IdeaWeatherPlugin.weather.put( "astronomy_sunrise", parseToken( astronomy, "sunrise" ) );
            IdeaWeatherPlugin.weather.put( "astronomy_sunset", parseToken( astronomy, "sunset" ) );

            // parse weather condition
            String condition = parseTag( response, "condition" );
            IdeaWeatherPlugin.weather.put( "condition_text", parseToken( condition, "text" ) );
            IdeaWeatherPlugin.weather.put( "condition_temp", parseToken( condition, "temp" ) );
            IdeaWeatherPlugin.weather.put( "condition_code", parseToken( condition, "code" ) );
            IdeaWeatherPlugin.weather.put( "condition_date", parseToken( condition, "date" ) );

            // parse forecast
            IdeaWeatherPlugin.forecast.clear();
            int startIndex = response.indexOf( "<yweather:forecast", 0 );
            while ( startIndex != -1 ) {
                int endIndex = response.indexOf( "/>", startIndex );
                String forecastHTML = response.substring( startIndex, endIndex );
                Map<String, String> map = new HashMap<String, String>();
                map.put( "forecast_day", parseToken( forecastHTML, "day" ).toUpperCase() );
                map.put( "forecast_date", parseToken( forecastHTML, "date" ) );
                map.put( "forecast_low", parseToken( forecastHTML, "low" ) );
                map.put( "forecast_high", parseToken( forecastHTML, "high" ) );
                map.put( "forecast_text", parseToken( forecastHTML, "text" ) );
                map.put( "forecast_code", parseToken( forecastHTML, "code" ) );
                IdeaWeatherPlugin.forecast.add( map );
                startIndex = response.indexOf( "<yweather:forecast", endIndex );
            }

            message = IdeaWeatherPlugin.weather.get( "condition_text" ) + ", " + IdeaWeatherPlugin.weather.get( "condition_temp" ) + "°" + IdeaWeatherPlugin.weather.get( "units_temperature" );
            code = IdeaWeatherPlugin.weather.get( "condition_code" );
        }

        IdeFrame[] ideFrames = WindowManager.getInstance().getAllProjectFrames();
        for ( IdeFrame frame : ideFrames ) {
            StatusBar statusBar = frame.getStatusBar();
            WeatherStatusBarWidget weatherStatusBarWidget = ( WeatherStatusBarWidget ) statusBar.getWidget( WeatherStatusBarWidget.ID );
            weatherStatusBarWidget.setCondition( message, code );
            statusBar.updateWidget( WeatherStatusBarWidget.ID );
        }
    }

    private String parseTag( String text,
                             String tag ) {
        int startIndex = text.indexOf( "<yweather:" + tag );
        int endIndex = text.indexOf( "/>", startIndex );
        return text.substring( startIndex, endIndex );
    }

    private String parseToken( String text,
                               String token ) {
        int startIndex = text.indexOf( token + "=\"" );
        int endIndex = text.indexOf( "\"", startIndex + token.length() + 2 );
        return text.substring( startIndex + token.length() + 2, endIndex );
    }
}
